package org.beanfuse.db.replication.wrappers;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.lang.StringUtils;
import org.beanfuse.collection.page.Page;
import org.beanfuse.collection.page.PageLimit;
import org.beanfuse.collection.page.SinglePage;
import org.beanfuse.db.dialect.Dialect;
import org.beanfuse.db.meta.ColumnMetadata;
import org.beanfuse.db.meta.DatabaseMetadata;
import org.beanfuse.db.meta.TableMetadata;
import org.beanfuse.db.meta.TypeUtils;
import org.beanfuse.db.replication.DataWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class DatabaseWrapper extends JdbcTemplate implements DataWrapper {
protected static Logger log = LoggerFactory.getLogger(DatabaseWrapper.class.getName());
protected DatabaseMetadata meta;
protected String catalog;
protected String productName;
protected String schema;
protected List tableNames = new ArrayList();
protected List viewNames = new ArrayList();
protected List sequenceNames = new ArrayList();
public DatabaseWrapper() {
super();
}
public DatabaseWrapper(String schema) {
super();
this.schema = schema;
}
public List getData(String tableName) {
TableMetadata tableMeta = meta.getTables().get(tableName);
if (null == tableMeta) {
return Collections.EMPTY_LIST;
} else {
return getData(tableMeta);
}
}
public int count(TableMetadata table) {
String sql = getQueryString(table);
String countStr = "select count(*) from (" + sql + ")";
return queryForInt(countStr);
}
public List getData(TableMetadata table, PageLimit limit) {
String sql = getQueryString(table);
String limitSql = meta.getDialect().getLimitString(sql, limit.getPageNo() > 1);
if (limit.getPageNo() == 1) {
return query(limitSql, new Object[] { limit.getPageSize() });
} else {
return query(limitSql, new Object[] { limit.getPageNo(), limit.getPageSize() });
}
}
public List getData(TableMetadata table) {
return query(getQueryString(table));
}
private String getQueryString(TableMetadata table) {
StringBuilder sb = new StringBuilder();
sb.append("select ");
String[] columnNames = table.getColumnNames();
for (String columnName : columnNames) {
sb.append(columnName).append(',');
}
sb.deleteCharAt(sb.length() - 1);
sb.append(" from ").append(table.getName());
return sb.toString();
}
public void pushData(final TableMetadata table, List datas) {
if (null == meta.getTableMetadata(table.identifier())) {
execute(table.sqlCreateString(meta.getDialect()));
}
final String[] columnNames = table.getColumnNames();
String insertSql = table.sqlInsertString();
try {
Connection conn = getDataSource().getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement(insertSql);
for (Object item : datas) {
final Object[] data = (Object[]) item;
for (int i = 0; i < columnNames.length; i++) {
ColumnMetadata cm = table.getColumnMetadata(columnNames[i]);
TypeUtils.setValue(ps, i + 1, data[i], cm.getTypeCode());
}
ps.execute();
}
ps.close();
conn.commit();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
}
public List query(String sql) {
return query(sql, (Object[]) null);
}
public List query(String sql, Object[] params) {
return query(sql, params, new RowMapper() {
public Object mapRow(ResultSet rs, int index) throws SQLException {
int columnCount = rs.getMetaData().getColumnCount();
if (columnCount == 1) {
return rs.getObject(1);
} else {
Object[] row = new Object[columnCount];
for (int i = 0; i < columnCount; i++) {
row[i] = rs.getObject(i + 1);
}
return row;
}
}
});
}
public void setMetadata(DatabaseMetadata metadata) {
this.meta = metadata;
}
public DatabaseMetadata getMetadata() {
return meta;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public Dialect getDialect() {
return meta.getDialect();
}
/**
* conntect to data source
*
* @param targetDB
* @param dialect
*/
public void connect(DataSource dataSource, Dialect dialect) {
try {
setDataSource(dataSource);
meta = new DatabaseMetadata(dataSource.getConnection(), dialect);
meta.loadAllMetadata(getSchema(), null, false);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}